<template>
    <div class="bi-input bi-field">

        <div class="input-group">
            <input
            ref="input"
            :type="inputType" 
            class="form-control" :class="[checkStatus?'':'is-invalid']"
            :style = "inputStyle"
            :placeholder="placeholder!=''?placeholder:parentPlaceholder" 
            :readonly="readonly" 
            :disabled="disabled"
            :id="id" 
            :name="id"
            :tabindex="tabindex"
            @input="baseCheck"
            v-model="value" />
        </div>

        <div class="bi-input-before" :style="breforeStyle" v-if="$slots.before || icon || loading">
            <slot name="before"></slot>
            <bi-icon v-if="icon || loading" class="bi-input-icon" :loading="loading" :data="icon" ></bi-icon>
            
        </div>
        
        <div class="bi-input-after" :style="afterStyle" v-if="$slots.after" >
            <slot name="after"></slot>
        </div>
    </div>
</template>

<script>
import FieldMixin from '../fieldMixin.js';
import {debounce} from '../global.js';

export default{
    mixins:[FieldMixin],
    computed:{
        inputType(){
            switch(this.type){
                case 'password':
                    return 'password';
                default:
                    return 'text';
            }
        },
        value:{
            get(){
                return this.modelValue;
            },
            set(val){

                let update = ()=>{
                    this.$emit('update:modelValue',val);
                    this.$emit('change',val);
                    this.valueChange(val);
                }
 

                update();
                
            }
        },
        breforeStyle(){
            
            let style = {};
            
            let width = 0;
            if(this.$slots.before)   width +=  parseInt(this.beforeWidth);
            if (this.icon || this.loading) width += 25;

            if (width>0){
                style.width = width + 'px';
            }

            return style;
        },
        afterStyle(){
            let style = {};
            let width = 0;
            if(this.$slots.after)   width +=  parseInt(this.afterWidth);
            if (width>0){
                style.width = width + 'px';
            }
            return style;
        },
        inputStyle(){

            let style  = {};

            if(this.$slots.before || this.icon || this.loading){
                
                style.paddingLeft = 0;
                
                if (this.icon || this.loading) style.paddingLeft += 30;
                if (this.beforeWidth) style.paddingLeft += parseInt(this.beforeWidth);
                style.paddingLeft += 'px';
            }

            if (this.$slots.after){
                style.paddingRight = 0;
                if (this.afterWidth) style.paddingRight += parseInt(this.afterWidth);
                style.paddingRight +='px';
            }

            if (this.fontStyle){
                for(let name in this.fontStyle){
                    style[name] = this.fontStyle[name];
                }
            }

            return style;
        }
    },
    methods:{
        check(){
            let rule = {};
            if(typeof this.rule == 'string' && this.rule !==''){
                rule.reg = this.rule;
            }

            if (typeof this.rule == 'object'){
            
                if (this.rule  instanceof RegExp){
                    rule.reg = this.rule;
                }else{
                    rule = this.rule;
                }
            }

            let value = this.value;

            if (this.type == 'number'){

                //判断是不是数字
                if (isNaN(value)){
                    return '请输入数字';
                }

                value = parseFloat(value);

            }

            if (this.type == 'int'){
 
                //正则判断是不是Int类型
                if (!/^[0-9]+$/.test(value)){
                    return '请输入整数';
                }

                value = parseFloat(value);
            }

            if (this.type == 'id-number'){

                // 正则判断是不是正确的身份证号
                if (!/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(value)){
                    return '请输入正确的身份证号';
                }
            }

            if (this.type == 'mobile'){
                if (!/^1[3456789]\d{9}$/.test(value)){
                    return '请输入正确的手机号';
                }
            }

            if (this.type == 'email'){
                if (!/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(value)){
                    return '请输入正确的邮箱';
                }
            }


            for(let name in rule){
                
                let ruleValue = rule[name];
                
                switch(name){
                    case 'reg':
                        if(!new RegExp(ruleValue).test(value)){
                            return this.getRuleMessage(name,ruleValue);
                        }
                        break;
                    case 'count':
                        if(value.length > parseInt(ruleValue)){
                            return this.getRuleMessage(name,ruleValue);
                        }
                    break;
                    case 'max':
                        
                        if(value > ruleValue){
                            return this.getRuleMessage(name,ruleValue);
                        }
                    break;
                    case 'min':
                         
                        if(value < ruleValue){
                            return this.getRuleMessage(name,ruleValue);
                        }
                    break;
                    default:
                        
                    break;
                }

            }
            
            return '';
        },
        getRuleMessage(name,value){

            if (typeof this.ruleMessage == 'object' && this.ruleMessage[name] ) return this.ruleMessage[name];
            if (typeof this.ruleMessage =='string' && this.ruleMessage!=='' ) return this.ruleMessage;

            $msg  = false;
            switch(name){
                case'reg':
                    $msg = '格式不正确';
                break;
                case 'count':
                    $msg = '长度不能大于' + value;
                break;
                case 'max':
                    $msg = '不能大于' + value;
                break;
                case 'min':
                    $msg = '不能小于' + value ;
                break;
                default:
                    $msg = '格式不正确';
                break;

            }

            return $msg;
        },
        focus(){
            this.$refs.input.focus();
        },
        
    },
    props:{
        type:{
            type:String,
            default:'text'
        },
        icon:{
            type:String,
            default:''
        },
        loading:{
            type:Boolean,
            default:false
        },
        beforeWidth:{
            type:[Number,String],
            default:0
        },
        afterWidth:{
            type:[Number,String],
            default:0
        },
        rule:{
            type:[Object,String],
            default:''
        },
        ruleMessage:{
            type:[Object,String],
            default:''
        },
        fontStyle:{
            type:Object,
            default:{}
        }
    },
    inject:{
        parentPlaceholder:{
            default(){
                return '';
            }
        },
    },
}
</script>


<style>
.bi-input-before,
.bi-input-after{
    position: absolute;
    top: 0;
    display: flex;
    align-items: center;
    z-index: 2;
    height: 100%;
    color: var(--bs-secondary-color);
}

.bi-input-before{
    left: 5px;
    justify-content: start;
}

.bi-input-after{
    right: 5px;
    justify-content:flex-end;
}

.bi-input{
    position: relative;
    z-index: 2;
}
.bi-input .bi-input-icon{
  margin-left: 5px;
  color: var(--bs-input-icon);
}


.input-group{
    position: relative;
    z-index: 1;
}

</style>
